package com.haixiaoke.saas.tenant.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.haixiaoke.saas.common.constant.TenantConstants;
import com.haixiaoke.saas.common.constant.UserConstants;
import com.haixiaoke.saas.common.core.domain.AjaxResult;
import com.haixiaoke.saas.common.core.domain.entity.SysMenu;
import com.haixiaoke.saas.common.enums.UserStatus;
import com.haixiaoke.saas.common.exception.ServiceException;
import com.haixiaoke.saas.common.oss.AliOssServiceImpl;
import com.haixiaoke.saas.common.utils.DateUtils;
import com.haixiaoke.saas.common.utils.TreeUtil.TreeUtil;
import com.haixiaoke.saas.role.domain.Role;
import com.haixiaoke.saas.role.domain.RoleMenu;
import com.haixiaoke.saas.role.service.IRoleMenuService;
import com.haixiaoke.saas.role.service.IRoleService;
import com.haixiaoke.saas.system.framework.security.util.SecurityUtils;
import com.haixiaoke.saas.system.service.ISysMenuService;
import com.haixiaoke.saas.tenant.domain.Tenant;
import com.haixiaoke.saas.tenant.domain.TenantMenu;
import com.haixiaoke.saas.tenant.domain.TenantTree;
import com.haixiaoke.saas.tenant.mapper.TenantMapper;
import com.haixiaoke.saas.tenant.service.ITenantMenuService;
import com.haixiaoke.saas.tenant.service.ITenantService;
import com.haixiaoke.saas.user.domain.UserBusiness;
import com.haixiaoke.saas.user.service.IUserBusinessService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 机构信息Service业务层处理
 *
 * @author panda
 * @date 2023-12-26
 */
@Service
public class TenantServiceImpl implements ITenantService {
    @Autowired
    private TenantMapper tenantMapper;
    @Autowired
    private AliOssServiceImpl aliOssService;
    @Autowired
    private IUserBusinessService userBusinessService;
    @Autowired
    private IRoleService roleService;
    @Autowired
    private ITenantMenuService tenantMenuService;
    @Autowired
    private ISysMenuService sysMenuService;
    @Autowired
    private IRoleMenuService roleMenuService;

    /**
     * 查询机构信息
     *
     * @return 机构信息
     */
    @Override
    public Tenant selectDepartmentByDepId(String tenantId) {
        return tenantMapper.selectDepartmentByTenantId(tenantId);
    }

    /**
     * 查询机构信息列表
     *
     * @param department 机构信息
     * @return 机构信息
     */
    @Override
    public List<Tenant> selectDepartmentList(Tenant department) {
        List<Tenant> departments = tenantMapper.selectDepartmentList(department);
        // departments.forEach( x-> x.setTypeList( x.getType().split(",") ));
        return departments;
    }

    /**
     * 新增机构信息
     *
     * @param tenant 机构信息
     * @return 结果
     */
    @Override
    @Transactional
    public AjaxResult insertDepartment(Tenant tenant) {
        int tenantResult = tenantMapper.countDepByName(tenant.getTenantName(), tenant.getTenantId());
        if (tenantResult > 0) {
            return AjaxResult.error("该机构名称已经存在");
        }
        Date nowDate = DateUtils.getNowDate();
        tenant.setCreateTime(nowDate);
        if (!StrUtil.equals("0", tenant.getParentId())) {
            tenant.setDepParentState(TenantConstants.DEP_PARENT_STATE_YES);
        }
        Tenant tenantById = tenantMapper.selectDepartmentByTenantId(tenant.getParentId());
        if (ObjectUtil.isNotEmpty(tenantById)) {
            if (StrUtil.equals(TenantConstants.TENANT_STATUS_NO, tenantById.getTenantState())) {
                AjaxResult.error("上级机构已停用，无法新增下级机构");
            }
            if (!StrUtil.equals(tenant.getParentId(), tenantById.getParentId())) {
                tenant.setAncestors(tenantById.getAncestors() + "," + tenant.getParentId());
            }
        } else {
            tenant.setAncestors(tenant.getParentId());
        }
        int result = tenantMapper.insertDepartment(tenant);
        if (result > 0) {

            if (userBusinessService.checkPhoneUnique(tenant.getPhonenumber())) {
                throw new ServiceException("新增用户'" + tenant.getPhonenumber() + "'失败，手机号码已存在");
            }

            SysMenu sysMenu = new SysMenu();
            sysMenu.setServerOwner(UserConstants.SERVER_OWNER_ENTERPRISE);
            List<SysMenu> sysMenus = sysMenuService.selectMenuList(sysMenu, 1L);
            List<Long> menuIds = sysMenus.stream().map(SysMenu::getMenuId).collect(Collectors.toList());

            Role role = new Role();
            role.setRoleName("主管理员");
            role.setRoleKey("admin");
            role.setRoleSort(0);
            role.setStatus("0");
            role.setTenantId(tenant.getTenantId());
            roleService.insertRole(role);

            List<TenantMenu> depMenuList = new ArrayList<>();
            List<RoleMenu> roleMenuList = new ArrayList<>();
            for (Long menuId : menuIds) {
                TenantMenu depMenu = new TenantMenu();
                depMenu.setTenantId(tenant.getTenantId());
                depMenu.setMenuId(menuId);
                depMenuList.add(depMenu);

                RoleMenu roleMenu = new RoleMenu();
                roleMenu.setRoleId(role.getRoleId());
                roleMenu.setMenuId(menuId);
                roleMenuList.add(roleMenu);
            }
            // 批量插入机构和菜单的关联数据
            if (!depMenuList.isEmpty()) {
                int rows = tenantMenuService.insertBatchDepMenu(depMenuList);
                if (rows != depMenuList.size()) {
                    throw new ServiceException("新增机构菜单关联数据失败");
                }
            }

            // 批量插入角色和菜单关联数据
            if (!roleMenuList.isEmpty()) {
                int rows = roleMenuService.insertBatchRoleMenu(roleMenuList);
                if (rows != depMenuList.size()) {
                    throw new ServiceException("新增角色菜单关联数据失败");
                }
            }

            UserBusiness user = new UserBusiness();
            user.setUserName(tenant.getPhonenumber());
            user.setPhonenumber(tenant.getPhonenumber());
            user.setPassword(SecurityUtils.encryptPassword(tenant.getPassword()));
            user.setStatus(UserStatus.OK.getCode());
            user.setTenantId(tenant.getTenantId());
            user.setPositionType("1");
            user.setRoleIds(new Long[]{role.getRoleId()});
            userBusinessService.insertBizUserBusiness(user);
        }
        return AjaxResult.success();
    }

    /**
     * 修改机构信息
     *
     * @param department 机构信息
     * @return 结果
     */
    @Override
    public int updateDepartment(Tenant department) {
        Tenant byDepId = tenantMapper.selectDepartmentByDepId(department.getTenantId());
        if (!StrUtil.equals(SecurityUtils.getLoginUser().getTenantId(), byDepId.getTenantId())) {
            throw new ServiceException("不能修改别人的机构信息");
        }

        Tenant department1 = new Tenant();
        department1.setTenantName(department.getTenantName());
        List<Tenant> departments = tenantMapper.selectDepartmentList(department1);
        if (CollectionUtil.isNotEmpty(departments)) {
            if (!byDepId.getTenantId().equals(department.getTenantId())) {
                throw new ServiceException("该机构名称已经存在");
            }
        }


        if (!StrUtil.equals(department.getIcon(), byDepId.getIcon())) {
            if (StrUtil.isNotBlank(byDepId.getIcon())) {
                // 删除原始oss图片
                aliOssService.delete(byDepId.getIcon());
            }
        }
        department.setUpdateTime(DateUtils.getNowDate());
        return tenantMapper.updateDepartment(department);
    }

    /**
     * 批量删除机构信息
     *
     * @param depIds 需要删除的机构信息主键
     * @return 结果
     */
    @Override
    public int deleteDepartmentByDepIds(String[] depIds) {
        tenantMenuService.deleteDepMenuByDepIds(depIds);
        //iTenantUserService.deleteTenantUserByTenantIds(depIds);
        return tenantMapper.deleteDepartmentByDepIds(depIds);
    }

    /**
     * 删除机构信息信息
     *
     * @param tenantId 机构信息主键
     * @return 结果
     */
    @Override
    public int deleteDepartmentByDepId(String tenantId) {
        return tenantMapper.deleteDepartmentByDepId(tenantId);
    }

    @Override
    public Tenant getElectronicVisaInfo(String tenantId) {
        return tenantMapper.selectDepartmentByTenantId(tenantId);
    }

    @Override
    @Transactional
    public AjaxResult manageUpdateDepartment(Tenant department) {
        int result = tenantMapper.countDepByName(department.getTenantName(), department.getTenantId());
        if (result > 0) {
            return AjaxResult.error("该机构名称已经存在");
        }
        // 校验用户数量
        int userNum = userBusinessService.countUserNumByTenantId(department.getTenantId());
        if (department.getMaxPopulation() < userNum && department.getMaxPopulation() != 0) {
            AjaxResult.error("用户最大数量小于当前机构用户数量");
        }
        // 校验手机号是否重复
        if (userBusinessService.checkPhoneUnique(department.getPhonenumber())) {
            AjaxResult.error("新增用户'" + department.getPhonenumber() + "'失败，手机号码已存在");
        }

        Tenant byDepId = tenantMapper.selectDepartmentByDepId(department.getTenantId());
        if (!StrUtil.equals(department.getIcon(), byDepId.getIcon())) {
            if (StrUtil.isNotBlank(byDepId.getIcon())) {
                // 删除原始oss图片
                aliOssService.delete(department.getIcon());
            }
        }
        department.setUpdateTime(DateUtils.getNowDate());
        int result1 = tenantMapper.updateDepartment(department);
        if (result1 > 0) {
            UserBusiness userBusiness = userBusinessService.selectUserManage(department.getTenantId());
            userBusiness.setPassword(SecurityUtils.encryptPassword(department.getPassword()));
            userBusiness.setPhonenumber(department.getPhonenumber());
            userBusinessService.updateBizUser(userBusiness);
        }
        return AjaxResult.success();
    }

    @Override
    public Tenant selectDepByDepId(String tenantId) {
        Tenant tenant = tenantMapper.selectDepartmentByDepId(tenantId);
        tenant.setParentIdList(StrUtil.split(tenant.getAncestors(), ","));
        return tenant;
    }

    /**
     * 设置机构权限菜单
     */
    @Override
    public int editMenuByDep(Tenant department) {
        // 删除机构和菜单关联数据
        tenantMenuService.deleteDepMenuByDepId(department.getTenantId());
        // 批量插入机构和菜单的关联数据
        int rows = 1;
        List<TenantMenu> depMenuList = new ArrayList<>();
        for (Long menuId : department.getMenuIds()) {
            TenantMenu depMenu = new TenantMenu();
            depMenu.setTenantId(department.getTenantId());
            depMenu.setMenuId(menuId);
            depMenuList.add(depMenu);
        }
        if (!depMenuList.isEmpty()) {
            rows = tenantMenuService.insertBatchDepMenu(depMenuList);
        }
        return rows;
    }

    @Override
    public List<Tenant> selectDepByUserId(Long userId) {
        return tenantMapper.selectDepByUserId(userId);
    }

    @Override
    public boolean checkPopulation(String tenantId) {
        Tenant department = tenantMapper.selectDepartmentByDepId(tenantId);
        int userNum = userBusinessService.countUserNumByTenantId(tenantId);
        if (department.getMaxPopulation() != 0 && department.getMaxPopulation() <= userNum) {
            return true;
        }
        return false;
    }

    @Override
    public int updateTenant(Tenant tenant) {
        return tenantMapper.updateDepartment(tenant);
    }

    @Override
    public List<String> selectAncestorsByTenantId(String tenantId) {
        return tenantMapper.selectAncestorsByTenantId(tenantId);
    }

    @Override
    public List<TenantTree> buildTreeList(Tenant tenant) {
        List<TenantTree> tenantLists = tenantMapper.selectTenantTreeList(tenant);
        return TreeUtil.generateTree(tenantLists);
    }

    @Override
    public AjaxResult editTenantState(String tenantId, String username) {
        Tenant tenant = tenantMapper.selectDepartmentByTenantId(tenantId);
        if (ObjectUtil.isEmpty(tenant)) {
            return AjaxResult.error("机构不存在");
        }
        if (StrUtil.equals(TenantConstants.TENANT_STATUS_NO, tenant.getTenantState())) {
            tenant.setTenantState(TenantConstants.TENANT_STATUS_YES);
        } else if (StrUtil.equals(TenantConstants.TENANT_STATUS_YES, tenant.getTenantState())) {
            tenant.setTenantState(TenantConstants.TENANT_STATUS_NO);
        }
        tenant.setUpdateBy(username);
        tenant.setUpdateTime(DateUtils.getNowDate());
        int result = tenantMapper.updateDepartment(tenant);
        return result > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    @Override
    public AjaxResult editBillState(String tenantId, String username) {
        Tenant tenant = tenantMapper.selectDepartmentByTenantId(tenantId);
        if (ObjectUtil.isEmpty(tenant)) {
            return AjaxResult.error("机构不存在");
        }
        if (StrUtil.equals(TenantConstants.GENERATE_BILL_NO, tenant.getGenerateBillState())) {
            tenant.setGenerateBillState(TenantConstants.GENERATE_BILL_YES);
        } else if (StrUtil.equals(TenantConstants.GENERATE_BILL_YES, tenant.getGenerateBillState())) {
            tenant.setGenerateBillState(TenantConstants.GENERATE_BILL_NO);
        }
        tenant.setUpdateBy(username);
        tenant.setUpdateTime(DateUtils.getNowDate());
        int result = tenantMapper.updateDepartment(tenant);
        return result > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 校验数据
     *
     * @param tenant
     */
    public void checkDepartment(Tenant tenant) {
        // if (tenant.getTypeList() == null || tenant.getTypeList().length == 0) {
        //     throw new ServiceException("机构类型为空");
        // }
        /*if (TenantConstants.DEP_PARENT_STATE_YES.equals(tenant.getDepParentState()) &&
                (tenant.getParentIdList() == null || tenant.getParentIdList().length == 0)) {
            throw new ServiceException("上级机构为空");
        }*/
        int result = tenantMapper.countDepByName(tenant.getTenantName(), tenant.getTenantId());
        if (result > 0) {
            throw new ServiceException("该机构名称已经存在");
        }
    }
}
